<?php
/**
 * 后台登录退出控制器
 * @author yupoxiong<i@yufuping.com>
 */

namespace app\admin\controller;

use app\admin\model\IndexTableModel;
use Exception;
use redis\RedisPackage;
use think\captcha\Captcha;
use think\Request;
use app\admin\model\AdminUser;
use app\admin\validate\AdminUserValidate;
use think\Validate;
use tools\GeeTest;
use tools\SafeCookie;
require_once (__DIR__.'/../../../vendor/ReidsLock.class.php');
require_once (__DIR__.'/../../../vendor/topthink/think-captcha/src/Captcha.php');
require_once (__DIR__.'/../../../vendor/topthink/think-captcha/src/helper.php');

class AuthController extends Controller
{

    protected $authExcept = [
        'admin/auth/login',
        'admin/auth/logout',
        'admin/auth/captcha',
        'admin/auth/initgeetest',
        'admin/auth/sendsmscode',

    ];

    //登录
    public function login(Request $request, AdminUser $model, AdminUserValidate $validate)
    {
        if ($request->isPost()) {

            $login_config = config('admin.login');

            $param = $request->param();

            //如果需要手机验证码
            if(isset($login_config['phone_code'])){
                if($login_config['phone_code'] == 1){
                    if(!isset($param['phone_code'])){
                        return admin_error('手机验证码未获取到');
                    }
                    if(empty($param['phone_code'])){
                        return admin_error('请填写手机验证码');
                    }
                    $codeRes = validatePhoneCode($param['username'],$param['phone_code']);
                    if($codeRes != 200){
                        return admin_error('手机验证码错误');
                    }
                }
            }

            //如果需要验证码
            if ($login_config['captcha'] > 0) {

                if ($login_config['captcha'] == 1) {
                    if (!captcha_check($param['captcha'])) {
                        return admin_error('验证码错误');
                    }
                } else if ($login_config['captcha'] == 2) {

//                    $config  = config('geetest.');
//                    $geeTest = new GeeTest($config['id'], $config['key']);
//
//                    $data = array(
//                        'user_id'     => session('gt_uid'),
//                        'client_type' => 'web',
//                        'ip_address'  => $request->ip(),
//                    );
//                    if (session('gt_server') == 1) {
//                        $gee_test_result = $geeTest->successValidate($param['geetest_challenge'], $param['geetest_validate'], $param['geetest_seccode'], $data);
//                        if (!$gee_test_result) {
//                            return admin_error('验证失败');
//                        }
//                    } else {
//                        if (!$geeTest->failValidate($param['geetest_challenge'], $param['geetest_validate'])) {
//                            return admin_error('验证失败');
//                        }
//                    }
                }
            }

            $validate_result = $validate->scene('login')->check($param);
            if (!$validate_result) {
                return admin_error($validate->getError());
            }

//            //如果需要验证登录token
//            if ($login_config['token']) {
//                $token_validate        = Validate::make();
//                $token_validate_result = $token_validate->rule('__token__', 'token')
//                    ->check($param);
//                if (!$token_validate_result) {
//                    return admin_error($token_validate->getError());
//                }
//            }

            try {
                $user = $model::login($param);
            } catch (Exception $e) {
                return admin_error($e->getMessage());
            }

            $remember = isset($param['remember']) ? true : false;
            self::authLogin($user, $remember);

            $redirect = session('redirect') ?? url('admin/index/index');


            //是否禁止同时多地登录   无操作退出登录分钟数===============================
            $login_config = config('admin.login');
            $user_id = $user['id'];
            $redis = New RedisPackage();
            //生成一个此用户得唯一登录标识 带有效期
            $token_user = time().rand(100,999);
            $token_time = bcmul($login_config['token_time'],60);
            $redis->set('adminlogin:'.$user_id,$token_user,$token_time);//唯一标识
            if($login_config['token'] == 1){
                //禁止同时多地登录
                SafeCookie::set('adminlogin:'.$user_id,$token_user);//登录标识
            }
            //===================================================================


            return admin_success('登录成功', $redirect);
        }
        $this->admin['title'] = '登录';

        $this->assign([
            //登录设置，参考/config/admin/admin.php文件配置
            'login_config' => config('admin.login'),
        ]);


        return $this->fetch();
    }

    //退出
    public function logout()
    {
        self::authLogout();
        return redirect(url('admin/auth/login'));
    }


    //极验初始化
    public function initGeeTest(Request $request)
    {

        $config  = config('geetest.');
        $geeTest = new GeeTest($config['id'], $config['key']);

        $ip = $request->ip();
        $ug = $request->header('user-agent');

        $data = array(

            'gt_uid'      => md5($ip . $ug),
            'client_type' => 'web',
            'ip_address'  => $ip,
        );

        $status = $geeTest->preProcess($data);

        session('gt_server', $status);
        session('gt_uid', $data['gt_uid']);

        return admin_success($status, URL_CURRENT, $geeTest->getResponse());
    }

    //ThinkPHP 图形验证码
    public function captcha()
    {
        $config  = [
            // 验证码字体大小
            'fontSize' => 30,
            // 验证码位数
            'length'   => 4,
            // 关闭验证码杂点
            'useNoise' => false,
        ];
        $captcha = new Captcha($config);
        return $captcha->entry();
    }


    /**
     * 发送手机验证码
     * User:@hang
     */
    public function sendsmscode()
    {
        $phone = input('username');
        //操作上锁
        $RedisLock  =  new \Redislock();
        $LockKey  =  'lock:adminsendsmscode'.$phone;	//定义锁标识
        $isLock  =  $RedisLock->lock($LockKey, 15);	//获取锁
        //解锁失败
        if(!$isLock){
            return admin_error('操作频繁，请稍后再试');
        }
        //查询是否存在此后台管理端账号
        $IndexTableModel = New IndexTableModel();
        $userInfo = $IndexTableModel->getFind('admin_user',"`username` = '{$phone}'",'id,status');
        if(empty($userInfo)){
            $RedisLock->unlock($LockKey);	//释放锁
            return admin_error('您的手机号用户名不是管理端账号，请检查');
        }
        if($userInfo['status'] != 1){
            $RedisLock->unlock($LockKey);	//释放锁
            return admin_error('您的后台管理端账号被封禁，请联系超级管理端');
        }
        $redis = new RedisPackage();
        $code = rand(100000,999999);//随机验证码
        //设置后台短信验证码有效期60分钟
        $redis->set('phoneCodeadmin:'.$phone,$code,3600);
        //执行发送手机短信
        $sendRes = $this->sendSms($phone,$code);
//        $sendRes['code'] = 200;//测试 默认都为成功
        if(isset($sendRes['code']) && $sendRes['code'] == 200){
            $RedisLock->unlock($LockKey);	//释放锁
            return admin_success('发送短信验证码成功');
        }else{
            $RedisLock->unlock($LockKey);	//释放锁
            return admin_error('发送短信验证码失败');
        }
    }


    /**
     * 发送手机验证码（阿里云）
     * User:@hang
     */
    public function sendSms($phone,$code)
    {
        $aliaccessKeyId = 'LTAI5t7z9G5JTNzezZd6bRAj';
        $aliAccessKeySecret = '1VDtHWYwk7KWZRikFra1I28AlPMGd5';

        $config = new \Darabonba\OpenApi\Models\Config([
            // 必填，您的 AccessKey ID
            "accessKeyId" => $aliaccessKeyId,
            // 必填，您的 AccessKey Secret
            "accessKeySecret" => $aliAccessKeySecret
        ]);
        // Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi
        $config->endpoint = "dysmsapi.aliyuncs.com";
        $client = New \AlibabaCloud\SDK\Dysmsapi\V20170525\Dysmsapi($config);
        $sendSmsRequest = new \AlibabaCloud\SDK\Dysmsapi\V20170525\Models\SendSmsRequest([
            "phoneNumbers" => $phone,
            "signName" => "哈尔滨壹言科技",
            "templateCode" => "SMS_480985159",
            "templateParam" => "{\"code\":\"$code\"}"
        ]);
        $runtime = new \AlibabaCloud\Tea\Utils\Utils\RuntimeOptions([]);
        $result = $client->sendSmsWithOptions($sendSmsRequest, $runtime);
        try {
            return ['code'=>200,'msg'=>'短信发送成功','data'=>['data'=>$result]];
        }catch (Exception $error) {
            return ['code'=>2001,'msg'=>'短信发送失败','data'=>[]];
        }
    }


}
